package skladowisko;

import java.util.ArrayList;
import java.util.List;
import obslugaTransportu.ObslugaZadania;
import skladowisko.dictonaries.StatusZadania;
import skladowisko.dictonaries.TypMaszyny;

/**
 *
 * @author Krzysiek
 */
public class Maszyna
{
    private int id;
    private static int nextId = 1;

    private String nazwa;
    private TypMaszyny typ;

    private Operator operator;
    private StanMaszyny stan = new StanMaszyny();
   
    //**************************************************************************
    public Maszyna(TypMaszyny typ)
    {
        this.typ = typ;
        this.id = nextId;
        nextId++;
    }
    //**************************************************************************
    public Maszyna()
    {
        this.typ = TypMaszyny.MASZYNA;
        this.id = nextId;
        nextId++;
    }
    //**************************************************************************
    public ObslugaZadania wykonaj(ZadaniePrzeladunkowe zadanie, boolean utorowany)
    {
        ObslugaZadania raport = new ObslugaZadania(zadanie, 0);
        
        zadanie.setMaszyna(this);
        zadanie.setStatus(StatusZadania.REALIZOWANE);

        if(!zadanie.isPoprawne())
            throw new IllegalStateException("parametry zadanie nie sa poprawne: " + zadanie.toString());

        wykonajPobranie(zadanie, raport);
        wykonajOddanie(zadanie, raport, utorowany);

        zadanie.setStatus(StatusZadania.ZAKONCZONE);
       
        return raport;
    }
    //**************************************************************************
    private void utorujDostep(Miejsce miejsce, ObslugaZadania raport)
    {
        if(miejsce instanceof Warstwa)
        {
            Warstwa warstwa = (Warstwa)miejsce;
            DostepDoPola dostep = warstwa.getPole().getSkladowisko().sprawdzDostep(warstwa.getPole());
            raport.dodajOperacje(2 * dostep.getIleOperacji());
        }
    }

    //**************************************************************************
    private void wykonajPobranie(ZadaniePrzeladunkowe zadanie, ObslugaZadania raport)
    {
       utorujDostep(zadanie.getSkad(), raport);

       if(zadanie.getSkad().isDostepne())
       {
            stan.trzymaj(zadanie.getSkad().sciagnij());
            raport.dodajOperacje();
       }
       else if (zadanie.getSkad() instanceof Warstwa)
       {
            Warstwa warstwa = (Warstwa)zadanie.getSkad();
            int i = warstwa.getPole().getZawartoscPola().getPierwszaWolna() - warstwa.getNumer() - 1;

            MiejsceTymczasowe[] tymczasowe = new MiejsceTymczasowe[i];
            int k = 0;
            do
            {
                tymczasowe[k] = przesunKontenerTymczasowo(warstwa.getPole().getZawartoscPola().sciagnijObiekt());
                k++;
                raport.dodajOperacje();
            }
            while(!zadanie.getSkad().isDostepne());

            MiejsceTymczasowe miejsceSzukanegoTMP = przesunKontenerTymczasowo(zadanie.getObiekt());

            for(int j=0; j<i;j++)
            {
                warstwa.getPole().getZawartoscPola().polozObiekt(tymczasowe[j].sciagnij());
            }

            stan.trzymaj(miejsceSzukanegoTMP.sciagnij());
       }
    }
    //**************************************************************************
    private MiejsceTymczasowe przesunKontenerTymczasowo(Kontener kontener)
    {
        stan.trzymaj(kontener);
        MiejsceTymczasowe tmp = new MiejsceTymczasowe(this, kontener.getMiejsce());
        tmp.poloz(kontener);
        stan.pusc();

        return tmp;
    }
    //**************************************************************************
    private void wykonajOddanie(ZadaniePrzeladunkowe zadanie, ObslugaZadania raport, boolean utorowany)
    {
        if(!utorowany)
            utorujDostep(zadanie.getDokad(), raport);

        if(zadanie.getDokad().isDostepne())
        {
            zadanie.getDokad().poloz(stan.pusc());
            if(raport.getIloscOperacji() > 1)
                raport.dodajOperacje();
        }
        else
        {            
            throw new IllegalArgumentException("Miejsce przeznaczenia kontenera jest niedostepne!!!");
        }
    }
    //**************************************************************************
    public int getId()
    {
        return id;
    }
    //**************************************************************************
    public String getNazwa()
    {
        return nazwa;
    }
    //**************************************************************************
    public void setNazwa(String nazwa)
    {
        this.nazwa = nazwa;
    }
    //**************************************************************************
    public TypMaszyny getTyp()
    {
        return typ;
    }
    //**************************************************************************
    public Operator getOperator()
    {
        return operator;
    }
    //**************************************************************************
    public void setOperator(Operator operator)
    {
        this.operator = operator;
    }
    //**************************************************************************
}
